// 扩展 Math 类型
declare global {
  interface Math {
    easeInOutQuad: (t: number, b: number, c: number, d: number) => number;
  }
}

// 缓动函数
Math.easeInOutQuad = function (t: number, b: number, c: number, d: number): number {
  t /= d / 2;
  if (t < 1) {
    return (c / 2) * t * t + b;
  }
  t--;
  return (-c / 2) * (t * (t - 2) - 1) + b;
};

// requestAnimationFrame polyfill
const requestAnimFrame: (callback: FrameRequestCallback) => number =
  window.requestAnimationFrame ||
  (window as any).webkitRequestAnimationFrame ||
  (window as any).mozRequestAnimationFrame ||
  function (callback: FrameRequestCallback): number {
    return window.setTimeout(callback, 1000 / 60);
  };

// 设置滚动位置
function move(amount: number) {
  document.documentElement.scrollTop = amount;
  (document.body.parentNode as HTMLElement).scrollTop = amount;
  document.body.scrollTop = amount;
}

// 获取当前滚动位置
function position(): number {
  return (
    document.documentElement.scrollTop ||
    ((document.body.parentNode as HTMLElement).scrollTop) ||
    document.body.scrollTop
  );
}

/**
 * 平滑滚动
 * @param to 目标位置
 * @param duration 持续时间 (默认 500ms)
 * @param callback 滚动结束回调
 */
export function scrollTo(to: number, duration: number = 500, callback?: () => void) {
  const start = position();
  const change = to - start;
  const increment = 20;
  let currentTime = 0;

  const animateScroll = function () {
    currentTime += increment;
    const val = Math.easeInOutQuad(currentTime, start, change, duration);
    move(val);

    if (currentTime < duration) {
      requestAnimFrame(animateScroll);
    } else {
      if (callback) callback();
    }
  };

  animateScroll();
}
